package com.longge.websocket.endpoint;

import java.io.IOException;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;

import com.alibaba.fastjson.JSONObject;
import com.longge.websocket.dto.ClientTextMessage;
import com.longge.websocket.util.MyMessageSenderUtils;
import com.longge.websocket.util.MySessionUtils;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class MyWebSocketHandler implements WebSocketHandler {
	private static final String SYSTEM = "system";

	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		String userId = (String) session.getAttributes().get("uid");
		log.info("session connect, userId:{}", userId);
		MySessionUtils.addSession(userId, session);
		MyMessageSenderUtils.sendTextMsgToAll(SYSTEM, "user：" + userId + " enter");
	}

	@Override
	public void handleMessage(WebSocketSession session, WebSocketMessage<?> msg) throws Exception {
		String userId = (String) session.getAttributes().get("uid");
		String message = msg.getPayload().toString();
		log.info("session send message, userId:{}, message:{}", userId, message);

		try {
			ClientTextMessage dto = JSONObject.parseObject(message, ClientTextMessage.class);
			if (StringUtils.isBlank(dto.getMessage())) {
				return;
			}
			if (StringUtils.isNotBlank(dto.getToUserId())) {
				boolean success = MyMessageSenderUtils.sendTextMsgToUser(userId, dto.getToUserId(), dto.getMessage());
				if (!success) {
					MyMessageSenderUtils.sendTextMsgToUser(SYSTEM, userId, "user " + dto.getToUserId() + " is offline");
				}
			} else {
				MyMessageSenderUtils.sendTextMsgToAll(userId, message);
			}
		} catch (Exception e) {
			log.error("Parsing foreground parameter error, close this session");
			try {
				MyMessageSenderUtils.sendTextMsgToUser(SYSTEM, userId, "Illegal request, socket close");
				MySessionUtils.removeSession(session);
				session.close();
			} catch (IOException e1) {
				log.error("session close error", e1);
			}
		}
	}

	@Override
	public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
		String userId = (String) session.getAttributes().get("uid");
		log.info("session error, userId:{}", userId);
	}

	@Override
	public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
		String userId = (String) session.getAttributes().get("uid");
		log.info("session close, userId:{}", userId);
		MyMessageSenderUtils.sendTextMsgToAll(SYSTEM, "user：" + userId + " leave");
	}

	/*
	 * 是否支持消息拆分发送：如果接收的数据量比较大，最好打开(true), 否则可能会导致接收失败。
	 * 如果出现WebSocket连接接收一次数据后就自动断开，应检查是否是这里的问题。
	 */
	@Override
	public boolean supportsPartialMessages() {
		return true;
	}

}
